package com.sylar.happyreader.view;

import java.io.IOException;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Path;
import android.graphics.PointF;
import android.graphics.Region;
import android.graphics.drawable.GradientDrawable;
import android.os.SystemClock;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Scroller;
import android.widget.Toast;

import com.sylar.happyreader.ReadBookActivity;
import com.sylar.happyreader.BookPagesActivity;
import com.sylar.happyreader.page.BookPageFactory;
import com.sylar.happyreader.tools.Config;

public class PageWidget extends SurfaceView implements SurfaceHolder.Callback, Runnable {

	private int mWidth = 480;
	private int mHeight = 800;
	private int mCornerX = 0;
	private int mCornerY = 0;
	private Path mPath0;
	private Path mPath1;
	// Bitmap mCurPageBitmap = null;
	// Bitmap mNextPageBitmap = null;

	PointF mTouch = new PointF(); //
	PointF mBezierStart1 = new PointF();
	PointF mBezierControl1 = new PointF();
	PointF mBeziervertex1 = new PointF();
	PointF mBezierEnd1 = new PointF();

	PointF mBezierStart2 = new PointF();
	PointF mBezierControl2 = new PointF();
	PointF mBeziervertex2 = new PointF();
	PointF mBezierEnd2 = new PointF();

	float mMiddleX;
	float mMiddleY;
	float mDegrees;
	float mTouchToCornerDis;
	ColorMatrixColorFilter mColorMatrixFilter;
	Matrix mMatrix;
	float[] mMatrixArray = { 0, 0, 0, 0, 0, 0, 0, 0, 1.0f };

	boolean mIsRTandLB;
	float mMaxLength = (float) Math.hypot(mWidth, mHeight);
	int[] mBackShadowColors;
	int[] mFrontShadowColors;
	GradientDrawable mBackShadowDrawableLR;
	GradientDrawable mBackShadowDrawableRL;
	GradientDrawable mFolderShadowDrawableLR;
	GradientDrawable mFolderShadowDrawableRL;

	// GradientDrawable mFrontShadowDrawableHBT;
	// GradientDrawable mFrontShadowDrawableHTB;
	// GradientDrawable mFrontShadowDrawableVLR;
	// GradientDrawable mFrontShadowDrawableVRL;

	Paint mPaint;

	Scroller mScroller;

	private Context mContext;

	private Bitmap mCurPageBitmap, mNextPageBitmap;
	private Canvas mCurPageCanvas, mNextPageCanvas;
	private BookPageFactory pagefactory;

	private boolean onScroll = false;

	private String msex;
	private String mstyle;
	private String mbookName;
	private float desity ;

	public PageWidget(Context context, int w, int h,String sex,String style,String bookname, Bitmap mCurPageBitmap, Bitmap mNextPageBitmap) throws OutOfMemoryError {
		super(context);

		m_SurfaceHolder = this.getHolder();
		m_SurfaceHolder.addCallback(this);
		
		desity = this.getResources().getDisplayMetrics().density;
		
		try {
			m_SurfaceHolder.setType(android.view.SurfaceHolder.SURFACE_TYPE_GPU);
		} catch (Exception e) {
			try {
				m_SurfaceHolder.setType(android.view.SurfaceHolder.SURFACE_TYPE_HARDWARE);
			} catch (Exception e2) {
				try {
					m_SurfaceHolder.setType(android.view.SurfaceHolder.SURFACE_TYPE_NORMAL);
				} catch (Exception e3) {
					// holy shit...
				}
			}
		}
		this.requestFocus();

		this.mWidth = w;
		this.mHeight = h;
		this.mContext = context;
		this.mPath0 = new Path();
		this.mPath1 = new Path();

		this.msex = sex;
		this.mstyle = style;
		this.mbookName = bookname;
		
		createDrawable();

		mPaint = new Paint();
		mPaint.setStyle(Paint.Style.FILL);

		ColorMatrix cm = new ColorMatrix();
		float array[] = { 0.55f, 0, 0, 0, 80.0f, 0, 0.55f, 0, 0, 80.0f, 0, 0, 0.55f, 0, 80.0f, 0, 0, 0, 0.2f, 0 };
		cm.set(array);
		mColorMatrixFilter = new ColorMatrixColorFilter(cm);
		mMatrix = new Matrix();
		mScroller = new Scroller(getContext());

		mTouch.x = 0.01f;
		mTouch.y = 0.01f;
		try {
			initpage(mCurPageBitmap, mNextPageBitmap);
		} catch (OutOfMemoryError e) {
			throw e;
		}

		// this.setBackgroundResource(R.drawable.cartoon_parchment_paper);
	}

	public void calcCornerXY(float x, float y) {
		if (x <= mWidth / 2)
			mCornerX = 0;
		else
			mCornerX = mWidth;
		if (y <= mHeight / 2)
			mCornerY = 0;
		else
			mCornerY = mHeight;
		if ((mCornerX == 0 && mCornerY == mHeight) || (mCornerX == mWidth && mCornerY == 0))
			mIsRTandLB = true;
		else
			mIsRTandLB = false;
	}

	public void initpage(Bitmap bmp1, Bitmap bmp2) {

		if (mCurPageBitmap == null) {
			mCurPageBitmap = bmp1;
			mCurPageCanvas = new Canvas(mCurPageBitmap);
		}
		if (mNextPageBitmap == null) {
			mNextPageBitmap = bmp2;
			mNextPageCanvas = new Canvas(mNextPageBitmap);
		}


		try {
			if (ReadBookActivity.msg != null) {
				pagefactory = new BookPageFactory(mContext, mWidth, mHeight,msex,mstyle,mbookName);
				pagefactory.openbook(ReadBookActivity.msg);
				pagefactory.onDraw(mCurPageCanvas);
				this.setBitmaps(mCurPageBitmap, mNextPageBitmap);
			}
		} catch (IOException e1) {
			e1.printStackTrace();
		}

	}

	int count = 0;
	float firClick = 0l;
	float secClick = 0l;

	boolean b = false;

	public boolean doTouchEvent(MotionEvent event) {
		synchronized (m_SurfaceHolder) {
			if (event.getAction() == MotionEvent.ACTION_DOWN && event.getY() > mHeight - (mHeight / 2) &&  event.getY() <= mHeight) {
				mTouch.x = event.getX();
				mTouch.y = event.getY();
				b = true;
				this.abortAnimation();
				this.calcCornerXY(event.getX(), event.getY());
				pagefactory.onDraw(mCurPageCanvas);
				if (this.DragToRight()) {
					try {
						pagefactory.prePage();
					} catch (IOException e1) {
						e1.printStackTrace();
					}
					if (pagefactory.isfirstPage()){
						mTouch.x = 0.01f;
						mTouch.y = 0.01f;
						b = false;
						Toast.makeText(mContext, "前面什么都没有哦^_^ .", 0).show();
						return false;
					}

					pagefactory.onDraw(mNextPageCanvas);

				} else {
					try {
						pagefactory.nextPage();
					} catch (IOException e1) {
						e1.printStackTrace();
					}
					if (pagefactory.islastPage() && ReadBookActivity.msg == null) {

						if (Config.pagelists.length > Config.pageNo + 1) {
							Toast.makeText(mContext, "文章正在加载中,请稍等再试哦^_^", 0).show();
						} else {
							mTouch.x = 0.01f;
							mTouch.y = 0.01f;
							b = false;
							Toast.makeText(mContext, "已经阅读到最后一章节.", 0).show();
						}
						return false;
					} else if (pagefactory.islastPage() && ReadBookActivity.msg != null && !"".equals(ReadBookActivity.msg)) {
						if (BookPagesActivity.dbCrud != null)
							BookPagesActivity.dbCrud.insert(mbookName.trim(), Config.nowPage.trim());
						Config.pageNo++;
						try {
							pagefactory.openbook(ReadBookActivity.msg);
							pagefactory.onDraw(mCurPageCanvas);
						} catch (IOException e1) {
							e1.printStackTrace();
						}
					}
					pagefactory.onDraw(mNextPageCanvas);

				}

			}
			if (event.getAction() == MotionEvent.ACTION_MOVE && event.getY() > mHeight / 2 && event.getY() < mHeight) {
				if (b) {
					mTouch.x = event.getX();
					mTouch.y = event.getY();
					// Log.d("yixs", "x : " + event.getX());
					// Log.d("yixs", "y : " + event.getY());
					// Log.d("yixs", "ACTION_MOVE");
					this.postInvalidate();
				}
			}

			if (event.getAction() == MotionEvent.ACTION_UP && event.getY() > mHeight / 2) {
				if (b) {
					startAnimation(1000);
					this.postInvalidate();
					b = false;
				}
			}

			return true;

		}

	}

	public PointF getCross(PointF P1, PointF P2, PointF P3, PointF P4) {
		PointF CrossP = new PointF();
		float a1 = (P2.y - P1.y) / (P2.x - P1.x);
		float b1 = ((P1.x * P2.y) - (P2.x * P1.y)) / (P1.x - P2.x);

		float a2 = (P4.y - P3.y) / (P4.x - P3.x);
		float b2 = ((P3.x * P4.y) - (P4.x * P3.y)) / (P3.x - P4.x);
		CrossP.x = (b2 - b1) / (a1 - a2);
		CrossP.y = a1 * CrossP.x + b1;
		return CrossP;
	}

	private void calcPoints() {
		mMiddleX = (mTouch.x + mCornerX) / 2;
		mMiddleY = (mTouch.y + mCornerY) / 2;
		mBezierControl1.x = mMiddleX - (mCornerY - mMiddleY) * (mCornerY - mMiddleY) / (mCornerX - mMiddleX);
		mBezierControl1.y = mCornerY;
		mBezierControl2.x = mCornerX;
		mBezierControl2.y = mMiddleY - (mCornerX - mMiddleX) * (mCornerX - mMiddleX) / (mCornerY - mMiddleY);

		mBezierStart1.x = mBezierControl1.x - (mCornerX - mBezierControl1.x) / 2;
		mBezierStart1.y = mCornerY;

		if (mTouch.x > 0 && mTouch.x < mWidth) {
			if (mBezierStart1.x < 0 || mBezierStart1.x > mWidth) {
				if (mBezierStart1.x < 0)
					mBezierStart1.x = mWidth - mBezierStart1.x;

				float f1 = Math.abs(mCornerX - mTouch.x);
				float f2 = mWidth * f1 / mBezierStart1.x;
				mTouch.x = Math.abs(mCornerX - f2);

				float f3 = Math.abs(mCornerX - mTouch.x) * Math.abs(mCornerY - mTouch.y) / f1;
				mTouch.y = Math.abs(mCornerY - f3);

				mMiddleX = (mTouch.x + mCornerX) / 2;
				mMiddleY = (mTouch.y + mCornerY) / 2;

				mBezierControl1.x = mMiddleX - (mCornerY - mMiddleY) * (mCornerY - mMiddleY) / (mCornerX - mMiddleX);
				mBezierControl1.y = mCornerY;

				mBezierControl2.x = mCornerX;
				mBezierControl2.y = mMiddleY - (mCornerX - mMiddleX) * (mCornerX - mMiddleX) / (mCornerY - mMiddleY);
				mBezierStart1.x = mBezierControl1.x - (mCornerX - mBezierControl1.x) / 2;
			}
		}
		mBezierStart2.x = mCornerX;
		mBezierStart2.y = mBezierControl2.y - (mCornerY - mBezierControl2.y) / 2;

		mTouchToCornerDis = (float) Math.hypot((mTouch.x - mCornerX), (mTouch.y - mCornerY));

		mBezierEnd1 = getCross(mTouch, mBezierControl1, mBezierStart1, mBezierStart2);
		mBezierEnd2 = getCross(mTouch, mBezierControl2, mBezierStart1, mBezierStart2);

		mBeziervertex1.x = (mBezierStart1.x + 2 * mBezierControl1.x + mBezierEnd1.x) / 4;
		mBeziervertex1.y = (2 * mBezierControl1.y + mBezierStart1.y + mBezierEnd1.y) / 4;
		mBeziervertex2.x = (mBezierStart2.x + 2 * mBezierControl2.x + mBezierEnd2.x) / 4;
		mBeziervertex2.y = (2 * mBezierControl2.y + mBezierStart2.y + mBezierEnd2.y) / 4;
	}

	private void drawCurrentPageArea(Canvas canvas, Bitmap bitmap, Path path) {
		mPath0.reset();
		mPath0.moveTo(mBezierStart1.x, mBezierStart1.y);
		mPath0.quadTo(mBezierControl1.x, mBezierControl1.y, mBezierEnd1.x, mBezierEnd1.y);
		mPath0.lineTo(mTouch.x, mTouch.y);
		mPath0.lineTo(mBezierEnd2.x, mBezierEnd2.y);
		mPath0.quadTo(mBezierControl2.x, mBezierControl2.y, mBezierStart2.x, mBezierStart2.y);
		mPath0.lineTo(mCornerX, mCornerY);
		mPath0.close();

		canvas.save();
		canvas.clipPath(path, Region.Op.XOR);
		canvas.drawBitmap(bitmap, 0, 0, null);
		canvas.restore();
	}

	private void drawNextPageAreaAndShadow(Canvas canvas, Bitmap bitmap) {
		mPath1.reset();
		mPath1.moveTo(mBezierStart1.x, mBezierStart1.y);
		mPath1.lineTo(mBeziervertex1.x, mBeziervertex1.y);
		mPath1.lineTo(mBeziervertex2.x, mBeziervertex2.y);
		mPath1.lineTo(mBezierStart2.x, mBezierStart2.y);
		mPath1.lineTo(mCornerX, mCornerY);
		mPath1.close();

		mDegrees = (float) Math.toDegrees(Math.atan2(mBezierControl1.x - mCornerX, mBezierControl2.y - mCornerY));
		int leftx;
		int rightx;
		GradientDrawable mBackShadowDrawable;
		if (mIsRTandLB) {
			leftx = (int) (mBezierStart1.x);
			rightx = (int) (mBezierStart1.x + mTouchToCornerDis / 4);
			mBackShadowDrawable = mBackShadowDrawableLR;
		} else {
			leftx = (int) (mBezierStart1.x - mTouchToCornerDis / 4);
			rightx = (int) mBezierStart1.x;
			mBackShadowDrawable = mBackShadowDrawableRL;
		}
		canvas.save();
		canvas.clipPath(mPath0);
		canvas.clipPath(mPath1, Region.Op.INTERSECT);
		canvas.drawBitmap(bitmap, 0, 0, null);
		canvas.rotate(mDegrees, mBezierStart1.x, mBezierStart1.y);
		mBackShadowDrawable.setBounds(leftx, (int) mBezierStart1.y, rightx, (int) (mMaxLength + mBezierStart1.y));
		mBackShadowDrawable.draw(canvas);
		canvas.restore();
	}

	public void setBitmaps(Bitmap bm1, Bitmap bm2) {
		mCurPageBitmap = bm1;
		mNextPageBitmap = bm2;
	}

	public void setScreen(int w, int h) {
		mWidth = w;
		mHeight = h;
		Log.i("__TRY__", "I'm here?");
	}

	protected void PrepareDraw(Canvas canvas) {
		calcPoints();
		canvas.drawColor(0xFFAAAAAA);
		canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
		drawCurrentPageArea(canvas, mCurPageBitmap, mPath0);
		drawNextPageAreaAndShadow(canvas, mNextPageBitmap);
		// drawCurrentPageShadow(canvas);
		drawCurrentBackArea(canvas, mCurPageBitmap);
	}

	private void createDrawable() {
		int[] color = { 0x333333, 0xb0333333 };
		if (mFolderShadowDrawableRL == null) {
			mFolderShadowDrawableRL = new GradientDrawable(GradientDrawable.Orientation.RIGHT_LEFT, color);
			mFolderShadowDrawableRL.setGradientType(GradientDrawable.LINEAR_GRADIENT);
		}

		if (mFolderShadowDrawableLR == null) {
			mFolderShadowDrawableLR = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, color);
			mFolderShadowDrawableLR.setGradientType(GradientDrawable.LINEAR_GRADIENT);
		}

		if (mBackShadowDrawableRL == null) {
			mBackShadowColors = new int[] { 0xff111111, 0x111111 };
			mBackShadowDrawableRL = new GradientDrawable(GradientDrawable.Orientation.RIGHT_LEFT, mBackShadowColors);
			mBackShadowDrawableRL.setGradientType(GradientDrawable.LINEAR_GRADIENT);
		}

		if (mBackShadowDrawableLR == null) {
			mBackShadowDrawableLR = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, mBackShadowColors);
			mBackShadowDrawableLR.setGradientType(GradientDrawable.LINEAR_GRADIENT);
		}

		// mFrontShadowColors = new int[] { 0x80111111, 0x111111 };
		// mFrontShadowDrawableVLR = new
		// GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT,
		// mFrontShadowColors);
		// mFrontShadowDrawableVLR.setGradientType(GradientDrawable.LINEAR_GRADIENT);
		// mFrontShadowDrawableVRL = new
		// GradientDrawable(GradientDrawable.Orientation.RIGHT_LEFT,
		// mFrontShadowColors);
		// mFrontShadowDrawableVRL.setGradientType(GradientDrawable.LINEAR_GRADIENT);
		//
		// mFrontShadowDrawableHTB = new
		// GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM,
		// mFrontShadowColors);
		// mFrontShadowDrawableHTB.setGradientType(GradientDrawable.LINEAR_GRADIENT);
		//
		// mFrontShadowDrawableHBT = new
		// GradientDrawable(GradientDrawable.Orientation.BOTTOM_TOP,
		// mFrontShadowColors);
		// mFrontShadowDrawableHBT.setGradientType(GradientDrawable.LINEAR_GRADIENT);
	}

	// public void drawCurrentPageShadow(Canvas canvas) {
	// double degree;
	// if (mIsRTandLB) {
	// degree = Math.PI / 4 - Math.atan2(mBezierControl1.y - mTouch.y, mTouch.x
	// - mBezierControl1.x);
	// } else {
	// degree = Math.PI / 4 - Math.atan2(mTouch.y - mBezierControl1.y, mTouch.x
	// - mBezierControl1.x);
	// }
	// double d1 = (float) 25 * 1.414 * Math.cos(degree);
	// double d2 = (float) 25 * 1.414 * Math.sin(degree);
	// float x = (float) (mTouch.x + d1);
	// float y;
	// if (mIsRTandLB) {
	// y = (float) (mTouch.y + d2);
	// } else {
	// y = (float) (mTouch.y - d2);
	// }
	// mPath1.reset();
	// mPath1.moveTo(x, y);
	// mPath1.lineTo(mTouch.x, mTouch.y);
	// mPath1.lineTo(mBezierControl1.x, mBezierControl1.y);
	// mPath1.lineTo(mBezierStart1.x, mBezierStart1.y);
	// mPath1.close();
	// float rotateDegrees;
	// canvas.save();
	//
	// canvas.clipPath(mPath0, Region.Op.XOR);
	// canvas.clipPath(mPath1, Region.Op.INTERSECT);
	// int leftx;
	// int rightx;
	// GradientDrawable mCurrentPageShadow;
	// if (mIsRTandLB) {
	// leftx = (int) (mBezierControl1.x);
	// rightx = (int) mBezierControl1.x + 25;
	// mCurrentPageShadow = mFrontShadowDrawableVLR;
	// } else {
	// leftx = (int) (mBezierControl1.x - 25);
	// rightx = (int) mBezierControl1.x + 1;
	// mCurrentPageShadow = mFrontShadowDrawableVRL;
	// }
	//
	// rotateDegrees = (float) Math.toDegrees(Math.atan2(mTouch.x -
	// mBezierControl1.x, mBezierControl1.y - mTouch.y));
	// canvas.rotate(rotateDegrees, mBezierControl1.x, mBezierControl1.y);
	// mCurrentPageShadow.setBounds(leftx, (int) (mBezierControl1.y -
	// mMaxLength), rightx, (int) (mBezierControl1.y));
	// mCurrentPageShadow.draw(canvas);
	// canvas.restore();
	//
	// mPath1.reset();
	// mPath1.moveTo(x, y);
	// mPath1.lineTo(mTouch.x, mTouch.y);
	// mPath1.lineTo(mBezierControl2.x, mBezierControl2.y);
	// mPath1.lineTo(mBezierStart2.x, mBezierStart2.y);
	// mPath1.close();
	// canvas.save();
	// canvas.clipPath(mPath0, Region.Op.XOR);
	// canvas.clipPath(mPath1, Region.Op.INTERSECT);
	// if (mIsRTandLB) {
	// leftx = (int) (mBezierControl2.y);
	// rightx = (int) (mBezierControl2.y + 25);
	// mCurrentPageShadow = mFrontShadowDrawableHTB;
	// } else {
	// leftx = (int) (mBezierControl2.y - 25);
	// rightx = (int) (mBezierControl2.y + 1);
	// mCurrentPageShadow = mFrontShadowDrawableHBT;
	// }
	// rotateDegrees = (float) Math.toDegrees(Math.atan2(mBezierControl2.y -
	// mTouch.y, mBezierControl2.x - mTouch.x));
	// canvas.rotate(rotateDegrees, mBezierControl2.x, mBezierControl2.y);
	// float temp;
	// if (mBezierControl2.y < 0)
	// temp = mBezierControl2.y - mHeight;
	// else
	// temp = mBezierControl2.y;
	//
	// int hmg = (int) Math.hypot(mBezierControl2.x, temp);
	// if (hmg > mMaxLength)
	// mCurrentPageShadow.setBounds((int) (mBezierControl2.x - 25) - hmg, leftx,
	// (int) (mBezierControl2.x + mMaxLength) - hmg, rightx);
	// else
	// mCurrentPageShadow.setBounds((int) (mBezierControl2.x - mMaxLength),
	// leftx, (int) (mBezierControl2.x), rightx);
	//
	// mCurrentPageShadow.draw(canvas);
	// canvas.restore();
	// }

	private void drawCurrentBackArea(Canvas canvas, Bitmap bitmap) {
		int i = (int) (mBezierStart1.x + mBezierControl1.x) / 2;
		float f1 = Math.abs(i - mBezierControl1.x);
		int i1 = (int) (mBezierStart2.y + mBezierControl2.y) / 2;
		float f2 = Math.abs(i1 - mBezierControl2.y);
		float f3 = Math.min(f1, f2);
		mPath1.reset();
		mPath1.moveTo(mBeziervertex2.x, mBeziervertex2.y);
		mPath1.lineTo(mBeziervertex1.x, mBeziervertex1.y);
		mPath1.lineTo(mBezierEnd1.x, mBezierEnd1.y);
		mPath1.lineTo(mTouch.x, mTouch.y);
		mPath1.lineTo(mBezierEnd2.x, mBezierEnd2.y);
		mPath1.close();
		GradientDrawable mFolderShadowDrawable;
		int left;
		int right;
		if (mIsRTandLB) {
			left = (int) (mBezierStart1.x - 1);
			right = (int) (mBezierStart1.x + f3 + 1);
			mFolderShadowDrawable = mFolderShadowDrawableLR;
		} else {
			left = (int) (mBezierStart1.x - f3 - 1);
			right = (int) (mBezierStart1.x + 1);
			mFolderShadowDrawable = mFolderShadowDrawableRL;
		}
		canvas.save();
		canvas.clipPath(mPath0);
		canvas.clipPath(mPath1, Region.Op.INTERSECT);

		mPaint.setColorFilter(mColorMatrixFilter);

		float dis = (float) Math.hypot(mCornerX - mBezierControl1.x, mBezierControl2.y - mCornerY);
		float f8 = (mCornerX - mBezierControl1.x) / dis;
		float f9 = (mBezierControl2.y - mCornerY) / dis;
		mMatrixArray[0] = 1 - 2 * f9 * f9;
		mMatrixArray[1] = 2 * f8 * f9;
		mMatrixArray[3] = mMatrixArray[1];
		mMatrixArray[4] = 1 - 2 * f8 * f8;
		mMatrix.reset();
		mMatrix.setValues(mMatrixArray);
		mMatrix.preTranslate(-mBezierControl1.x, -mBezierControl1.y);
		mMatrix.postTranslate(mBezierControl1.x, mBezierControl1.y);
		canvas.drawBitmap(bitmap, mMatrix, mPaint);
		mPaint.setColorFilter(null);
		canvas.rotate(mDegrees, mBezierStart1.x, mBezierStart1.y);
		mFolderShadowDrawable.setBounds(left, (int) mBezierStart1.y, right, (int) (mBezierStart1.y + mMaxLength));
		mFolderShadowDrawable.draw(canvas);
		canvas.restore();
	}

	public void computeScroll() {
		super.computeScroll();
		if (mScroller.computeScrollOffset() && onScroll) {
			float x = mScroller.getCurrX();
			float y = mScroller.getCurrY();
			mTouch.x = x;
			mTouch.y = y;
			postInvalidate();
		} else {
			onScroll = false;
		}
	}

	private void startAnimation(int delayMillis) {
		int dx, dy;
		if (mCornerX > 0) {
			dx = -(int) (mWidth + mTouch.x);
		} else {
			dx = (int) (mWidth - mTouch.x + mWidth);
		}
		if (mCornerY > 0) {
			dy = (int) (mHeight - mTouch.y);
		} else {
			dy = (int) (1 - mTouch.y);
		}
		onScroll = true;
		mScroller.startScroll((int) mTouch.x, (int) mTouch.y, dx, dy, delayMillis);

	}

	public void abortAnimation() {
		if (!mScroller.isFinished()) {
			mScroller.abortAnimation();
		}
	}

	public boolean canDragOver() {
		if (mTouchToCornerDis > mWidth / 10)
			return true;
		return false;
	}

	public boolean DragToRight() {
		if (mCornerX > 0)
			return false;
		return true;
	}

	
	protected void onDetachedFromWindow() {
		super.onDetachedFromWindow();
	}

	
	public void run() {
		while (m_bCreated) {
			long currentTime = SystemClock.uptimeMillis();
			if (0 == m_iLastTick) {
				m_iLastTick = currentTime;
			} else if (currentTime - m_iLastTick >= 50) {
				m_iLastTick = currentTime;
				synchronized (m_SurfaceHolder) {
					DrawSurface();
				}
			}
		}

	}

	SurfaceHolder m_SurfaceHolder;
	boolean m_bCreated;
	boolean m_bAllPrepared;
	long m_iLastTick;

	private void DrawSurface() {
		Canvas inCanvas = m_SurfaceHolder.lockCanvas();
		if (null == m_SurfaceHolder || null == inCanvas) {
			return;
		}
		PrepareDraw(inCanvas);
		m_SurfaceHolder.unlockCanvasAndPost(inCanvas);
	}

	
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
	}

	
	public void surfaceCreated(SurfaceHolder holder) {
		m_bCreated = true;
		m_iLastTick = 0;
		new Thread(this).start();
	}

	
	public void surfaceDestroyed(SurfaceHolder holder) {
		m_bCreated = false;
	}
}
